iT邦幫忙

2022 iThome 鐵人賽

DAY 17
2
自我挑戰組

PixelBit 可以這樣玩!系列 第 17

(Day 17)一起玩 Dino Game 小恐龍遊戲(Part 2)

  • 分享至 

  • xImage
  •  

這篇文章將會接續上一篇「一起玩 Dino Game 小恐龍遊戲(Part 1)」。

教學原文參考:一起玩 Dino Game 小恐龍遊戲

五、程式解析

1. 牛刀小試

我們先從最簡單的顯示開始,請開啟名稱為「PixelBit_Image_Show」的資料夾。

https://lh5.googleusercontent.com/UQ749VYQGeAFKA8nEkD2EyF_mirCeq9Tjv7BLLNdVAcc8pN3dQbyxFQgNFdm1n5MFB7NFMo3UcFa3A-zPXUa96VkvRanNPUDPV0Es-VZ-1WwTiUev15Bg__0h6EC7JyIxcYeE7CWMY-CG52ZYA

打開裡面的程式,完整程式如下:

https://www.circuspi.com/wp-content/uploads/2022/05/08.jpg

與之前的顯示程式最大的不同,就是新加入了「Sprite」功能,Sprite 功能就像是一個可以自由設定大小的獨立畫布,您可以把圖形繪製到這個獨立的畫布上,並且可以同時擁有多個 Sprite,方便管理。最大優點是Sprite 之間可以重疊,例如在背景存在的情況下,我們可以建置恐龍的 Sprite 與仙人掌的 Sprite,並將它們像貼貼紙一樣黏在背景上。

程式碼中的第三行,我們建立了一個預備使用 Sprite 的物件「img」,接著我們將剛剛圖片轉換成的資料放在「PROGMEM unsigned char dino[]」裡面。

在「setup()」區塊的部份,透過「createSprite(33, 35)」創建了一個大小與恐龍圖片一樣的 Sprite,接著由「drawXBitmap(0, 0, dino, 33, 35, TFT_BLACK, TFT_WHITE)」將恐龍繪製上去,括弧內前兩個參數表示繪製的起始座標,接著是圖檔、圖檔大小、與顯示色彩和背景色彩。

最後由「pushSprite(105, 104)」設定好要顯示在螢幕的座標位子後,圖片就會出現在螢幕上了。

https://www.circuspi.com/wp-content/uploads/2022/05/09.jpg

2. ATmega328p 的程式

遊戲執行的過程只有單純的按鈕輸入與螢幕顯示,螢幕的部份歸 ESP32 負責,ATmega328p 只有負責按鈕的部份。聰明的大家應該猜的到,不就是單純讀取按鈕是否有按下,然後再發送訊息通知 ESP32 這麼簡單嗎?沒錯!

您可以依照「Pixel:Bit 教學(二)」的做法自己撰寫這個程式,想要挑戰的朋友可以自己設計看看。為了能與待會的 ESP32 程式溝通,您需要設計按鈕 A 與按鈕 B,分別按下與放開的指令,如下表所示:

https://www.circuspi.com/wp-content/uploads/2022/05/10-1.jpg

只要朝這個方向設計,就能直接接軌待會的 ESP32 程式。範例程式這邊給出不一樣的思路給大家參考,現在請開啟名稱為「PixelBit_Dino_Game_328p」的資料夾,並打開程式。

程式有主程式「PixelBit_Dino_Game_328p.ino」與副程式「config.h」,副程式 config.h 是用於設定參數與對照表,類似將一些較攏長的指令與變數定義全部集合在這裡,再由程式匯入副程式這個檔案,取用裡面的內容。

主程式則是將一些常用的功能或是自定義的功能全寫在裡面,除了這個單元會用上的按鈕 A(左邊按鈕)及按鈕 B(右邊按鈕)之外,也將上個單元的遙控車控制馬達的功能,一併放在這裡。

https://www.circuspi.com/wp-content/uploads/2022/05/11-1.jpg

主程式看似複雜,但仔細研讀會發現,這樣系統化的做法可讓往後擴充更便利,程式碼也較整齊。

上述給大家做參考,同時鼓勵大家可以用自己理解的方式寫寫看。不論您是自己撰寫,還是直接取用範例程式,都不要忘記將程式先燒錄到 ATmega328p 內。

3. ESP32 的程式

比起 ATmega328p,ESP32 這邊的程式就複雜許多,雖說是顯示而已,但顯示遊戲內容還是比單純的文字和圖形複雜的多。請開啟名稱為「PixelBit_Dino_Game_esp32.ino」的資料夾,並打開程式。

程式由五個部份組成,分別是主程式與其他四個副程式,「config.h」這個副程式與 ATmega328p
那邊的功用相同,都是用來存放一些設定的參數與對應的變數。其餘三個副程式都是用來存放圖檔,「noInternet.h」存放的是遊戲開始畫面,完美呈現沒有網路的無奈畫面。「gameover.h」存放的是小恐龍撞到障礙物時,結束遊戲的畫面。

「imgData.h」則分別存放小恐龍(三個畫面)、雲朵(一個畫面)、路面凸起小土丘(兩個畫面)與障礙物(兩個畫面)。有些項目會有多個畫面是為了增加豐富性,例如恐龍在移動時會需要多個畫面交叉顯示,這樣看起來才會像跑動的樣子。

了解其餘副程式的功能後,讓我們回來看主程式,首先與剛剛牛刀小試裡介紹的一樣,我們需要創造幾個「Sprite」來放置圖形。

https://lh4.googleusercontent.com/34ehUlspvZ6nIbgZXj31_wYSNKqgUMhHjhKGicAu1zIdGeJFwud8PRG9_oZOvfalr3uttIhueTZf07vh_wdktX7UtWsvonhgMjvZnYkXVFLPQ6zJaEnglvGbnz9ckUZRJOcoteZLv8JuNOJrpw

「img」用來放置背景的元素,「img2」專門放置小恐龍,「e」、「e2」則是分別放置兩種不同造型的障礙物。

讀取從 ATmega328p 送過來的按鈕資訊部份就不解釋了,掌管圖形顯示與變化最關鍵的程式是圖中的「drawS()」。

https://lh5.googleusercontent.com/6qnBLKu2P8xynQY-ZrVtPS4H33BGIUFl3g_rQUEDOrpzniVPo9BvxU24C8P38Ql2f9EklfwZaL5i-I0xMYLf7pLbpjtF_rV5KMgPBKJQ_qWHbHkCdh3pz3_Vc3vc_SAT0W52tt4Vrmte226Ftw

「drawS()」負責處理背景的線條與隨機放置小土丘、雲朵和障礙物,小恐龍會依照按下按鈕而有跳起和落下的動畫,沒按按鈕時會有跑動的動畫。

另一個重要的程式是「checkColision()」,用來確認小恐龍有沒有撞上障礙物,有的話會停止遊戲並顯示「遊戲結束畫面」。

https://lh3.googleusercontent.com/31NL_u0SPrCPWeRUZ1BlDg3qc75x9GxSFnft8rYy2QYGz2FHVkk300b-N4nGw5RvKf-gmOMHb7qm-mBWjixWSHGmktfzVwlbshOcRRhxesq0ZfFhizvIpdsUdSN_x2ATVt7AzWqnJtGvNXsiwQ

在「loop()」裡運行的完整流程,第一步先確認是否有收到從 ATmega328p 傳送過來的按鈕訊息,第二步則是依照按鈕狀態調整小恐龍的動作,看是要繼續跑動還是跳起與落下。接著統一顯示所有圖像,雲朵、障礙物和背景……等,最後確認小恐龍有沒有撞上障礙物。讓我們將程式燒錄到 ESP32 裡面。

4. 實際操作展示

現在就讓我們開始玩遊戲吧!

https://www.circuspi.com/wp-content/uploads/2022/05/2-3.gif

六、結論

這個單元教了大家除了影像辨識外的趣味專案,我們完成了在 Pixel:bit 運行 Chrome Dino Game。像這樣簡單的小遊戲,其實還有很多種,只要是能單靠兩顆按鈕操作的遊戲,您都能透過自己的想像力與程式碼將這些遊戲移到 Pixel:bit 上面,還不趕緊製作屬於自己的遊戲跟朋友們分享!

更多有趣系列教學文章


上一篇
(Day 16)一起玩 Dino Game 小恐龍遊戲(Part 1)
下一篇
(Day 18)影像辨識機械手臂(Part 1)
系列文
PixelBit 可以這樣玩!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言